package com.fc.advbox.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.fc.advbox.dao.BaseDao;
import com.fc.advbox.dao.EquipmentDailyProfitDao;
import com.fc.advbox.entity.EquipmentDailyProfitEntity;
import com.fc.advbox.entity.EquipmentHoldingEntity;
import com.fc.advbox.model.org.OrgMonthProfit;
import com.fc.advbox.service.IEquipmentDailyProfitService;
import com.fc.advbox.service.IEquipmentHoldingService;
import com.fc.advbox.service.IOrgAcctService;
import com.fc.advbox.utils.Constant;
import com.fc.advbox.utils.DateTimeHelper;
import com.google.common.collect.Maps;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * Created by E7450 on 2018/7/2.
 */
@Service("equipmentDailyProfitService")
public class EquipmentDailyProfitServiceImpl extends BaseServiceImpl<EquipmentDailyProfitEntity> implements IEquipmentDailyProfitService {

    @Autowired
    private EquipmentDailyProfitDao equipmentDailyProfitDao;

    @Autowired
    private IEquipmentHoldingService equipmentHoldingService;

    @Autowired
    private IOrgAcctService orgAcctService;

    @Override
    public BaseDao getDao() {
        return equipmentDailyProfitDao;
    }


    public void calculateEquipmentDailyProfit(Date currentTime)
    {
        BigDecimal bigDecimal_100 = new BigDecimal(100);
        Map<String, Object> params = Maps.newHashMap();
        params.put("currentTime", currentTime);
        List<EquipmentHoldingEntity> equipmentHoldingList = equipmentHoldingService.queryAllCurrentActiveRentHoldings(params);
        if(equipmentHoldingList == null || equipmentHoldingList.isEmpty())
        {
            return;
        }

        for(EquipmentHoldingEntity equipmentHoldingEntity: equipmentHoldingList)
        {
            if(equipmentHoldingEntity == null)
            {
                continue;
            }

            EquipmentDailyProfitEntity dailyProfitEntity = new EquipmentDailyProfitEntity();
            dailyProfitEntity.setEquipmentId(equipmentHoldingEntity.getEquipmentId()); // 设备ID
            dailyProfitEntity.setOwnerOrgId(equipmentHoldingEntity.getOwnerOrgId());   // 所有者的机构ID，默认是国鑫智能
            dailyProfitEntity.setSettleDate(new Date());                               // 结算日期
            dailyProfitEntity.setRentOrgId(equipmentHoldingEntity.getRentOrgId());     // 广告商、租赁商户的机构ID
            dailyProfitEntity.setCost(Constant.DEFAULT_EQUIPMENT_DAILY_COST); // 设置日损耗


            // 当日广告净收入 = 当日广告总收入 - 机器日损耗费用
            BigDecimal dailyNetRevenue = calculateDailyNetRevenue(equipmentHoldingEntity.getRentPrice(), dailyProfitEntity.getCost());

            // 计算代理商的 天利润
            if(equipmentHoldingEntity.getAgentStartTime() != null
                    && equipmentHoldingEntity.getAgentEndTime() != null
                    && currentTime.after(equipmentHoldingEntity.getAgentStartTime())
                    && currentTime.before(equipmentHoldingEntity.getAgentEndTime()))
            {
                dailyProfitEntity.setAgentOrgId(equipmentHoldingEntity.getAgentOrgId()); // 代理商的机构ID

                // 代理商日收益
                if(equipmentHoldingEntity.getAgentRate() == null)
                {
                    dailyProfitEntity.setAgentProfit(BigDecimal.ZERO);
                }
                else
                {
                    // 代理商日收益 = 日净收益 * 代理商收益比例
                    dailyProfitEntity.setAgentProfit(dailyNetRevenue.multiply(equipmentHoldingEntity.getAgentRate()).divide(bigDecimal_100, 2, BigDecimal.ROUND_DOWN));
                }
            }

            // 计算渠道商的 天利润
            if(equipmentHoldingEntity.getChannelStartTime() != null
                    && equipmentHoldingEntity.getChannelEndTime() != null
                    && currentTime.after(equipmentHoldingEntity.getChannelStartTime())
                    && currentTime.before(equipmentHoldingEntity.getChannelEndTime()))
            {
                dailyProfitEntity.setChannelOrgId(equipmentHoldingEntity.getChannelOrgId()); // 渠道商的机构ID
                // 渠道商de日收益
                if(equipmentHoldingEntity.getChannelRate() == null)
                {
                    dailyProfitEntity.setChannelProfit(BigDecimal.ZERO);
                }
                else
                {
                    // 渠道商日收益 = 日净收益 * 渠道商收益比例
                    dailyProfitEntity.setChannelProfit(dailyNetRevenue.multiply(equipmentHoldingEntity.getChannelRate()).divide(bigDecimal_100, 2, BigDecimal.ROUND_DOWN));
                }
            }

            // 当日owner收入 = 当日净收入 - 当日代理商收益 - 当日渠道商收益
            // 当日净收入 = 当日总收入 - 当日损耗
            dailyProfitEntity.setIncome(dailyNetRevenue.subtract(calculateDailyCustomerProfit(dailyProfitEntity)));

            // 新增或更新当天利润记录
            saveOrUpdateDailyProfit(dailyProfitEntity);
        }
    }

    /**
     * 计算该机器当日代理商和渠道商的总支出
     * @param dailyProfitEntity
     * @return
     */
    private BigDecimal calculateDailyCustomerProfit(EquipmentDailyProfitEntity dailyProfitEntity)
    {
        if(dailyProfitEntity.getAgentProfit() != null && dailyProfitEntity.getChannelProfit() != null)
        {
            return dailyProfitEntity.getAgentProfit().add(dailyProfitEntity.getChannelProfit());
        }
        else if(dailyProfitEntity.getAgentProfit() != null && dailyProfitEntity.getChannelProfit() == null)
        {
            return dailyProfitEntity.getAgentProfit();
        }
        else if(dailyProfitEntity.getChannelProfit() != null && dailyProfitEntity.getAgentProfit() == null)
        {
            return dailyProfitEntity.getChannelProfit();
        }
        return BigDecimal.ZERO;
    }

    /**
     * 计算日净利润，  日净利润 = 日总收益 - 日损耗
     * @param dailyTotalRentPrice -- 日总收益
     * @param dailyCost -- 日损耗
     * @return
     */
    private BigDecimal calculateDailyNetRevenue(BigDecimal dailyTotalRentPrice, BigDecimal dailyCost)
    {
        if(dailyCost == null)
        {
            dailyCost = BigDecimal.ZERO;
        }
        if(dailyTotalRentPrice != null)
        {
            // TODO 日花费，日损耗 暂时 hardCode， 自定义为0
            BigDecimal dailyNetRevenue = dailyTotalRentPrice.subtract(dailyCost);
            // 日总收益 -  日损耗 < 0 , 则 日净收益 返回 0
            if( dailyNetRevenue.compareTo(BigDecimal.ZERO)== -1)
            {
                return BigDecimal.ZERO;
            }
            return  dailyNetRevenue;
        }
        return BigDecimal.ZERO;
    }

    /**
     * 新增或更新当天利润记录
     * @param dailyProfitEntity
     */
    private void saveOrUpdateDailyProfit(EquipmentDailyProfitEntity dailyProfitEntity)
    {
        // 查询当天该机器是否已经计算过利润
        if(dailyProfitEntity.getSettleDate() == null)
        {
            dailyProfitEntity.setSettleDate(new Date());
        }
        Map<String, Object> profitParams = Maps.newHashMap();
        profitParams.put("equipmentId", dailyProfitEntity.getEquipmentId());
        profitParams.put("settleDate", DateTimeHelper.getStringFromDate(dailyProfitEntity.getSettleDate(), DateTimeHelper.PAYLOAD_DATEONLY));
        List<EquipmentDailyProfitEntity> equipmentDailyProfitEntityList = equipmentDailyProfitDao.queryList(profitParams);

        // 如果未计算过，则新增一条日利润记录
        if(equipmentDailyProfitEntityList != null && !equipmentDailyProfitEntityList.isEmpty())
        {
            // 如果已有计算过的日利润记录，则先删除后在重新保存
            for(EquipmentDailyProfitEntity entity : equipmentDailyProfitEntityList)
            {
                // 理论上每台设备每天只有一条记录
                equipmentDailyProfitDao.delete(entity.getId());
            }
        }

        // 保存该机器当日的利润分配
        equipmentDailyProfitDao.save(dailyProfitEntity);
    }

    /**
     * 根据日收益，增加代理商和渠道商的账号收益
     * @param dateTime
     */
    public List<OrgMonthProfit> queryAgentAndChannelMonthProfitList(Date dateTime)
    {
        List<OrgMonthProfit> orgMonthProfitList = new ArrayList<>();
        if(dateTime == null)
        {
            return orgMonthProfitList;
        }
        JSONObject params = new JSONObject();
        params.put("startDate", DateTimeHelper.getStringFromDate(DateTimeHelper.getStartOfMonth(dateTime), DateTimeHelper.URI_DATEONLY)); // 当月第一天的时间，并转换格式为 'yyyyMMdd' , 例如:20180701
        params.put("endDate", DateTimeHelper.getStringFromDate(DateTimeHelper.getEndOfMonth(dateTime), DateTimeHelper.URI_DATEONLY)); // 当月最后一天的时间，并转换格式为 'yyyyMMdd' , 例如:20180731

        // 计算代理商当月的月收益
        orgMonthProfitList.addAll(equipmentDailyProfitDao.calculateAgentMonthProfit(params));

        // 计算渠道商当月的月收益
        orgMonthProfitList.addAll(equipmentDailyProfitDao.calculateChannelMonthProfit(params));

        // 计算国鑫智能当月的月收益
        orgMonthProfitList.addAll(equipmentDailyProfitDao.calculateOwnerMonthProfit(params));

        return orgMonthProfitList;
    }
}
